Libreias
library(tidyverse)
library (car)
library (ridge)
Data
TT <- read_csv("../../data/periods.csv")
Parsed with column specification:
cols(
V1 = [32mcol_double()[39m,
V2 = [32mcol_double()[39m,
V3 = [32mcol_double()[39m,
V4 = [32mcol_double()[39m,
V5 = [32mcol_double()[39m,
V6 = [32mcol_double()[39m
)
Satelites malo
badsat <- read_csv("BADSAT.txt")
Parsed with column specification:
cols(
sat_id = [32mcol_double()[39m
)
badsat
Normal regression
for (i in unique(badsat$sat_id)){
print(i)
ddi <- filter(dd, sat_id==i)
testi <- filter(dd, sat_id==i)
testi <- rbind(select(testi, id, sat_id, epoch, x_sim, y_sim, z_sim, Vx_sim, Vy_sim, Vz_sim), filter(test, sat_id==i))
t1 <- unlist(TT[i+1,1])
t2 <- unlist(TT[i+1,2])
t3 <- unlist(TT[i+1,3])
t4 <- unlist(TT[i+1,4])
t5 <- unlist(TT[i+1,5])
t6 <- unlist(TT[i+1,6])
lmX <- lm(x ~ epoch+sin(2*pi/t1*epoch)+cos(2*pi/t1*epoch)+sin(4*pi/t1*epoch)+cos(4*pi/t1*epoch)+sin(6*pi/t1*epoch)+cos(6*pi/t1*epoch)+sin(8*pi/t1*epoch)+cos(8*pi/t1*epoch)+sin(10*pi/t1*epoch)+cos(10*pi/t1*epoch)+epoch*sin(2*pi/t1*epoch)+epoch*cos(2*pi/t1*epoch)+epoch*sin(4*pi/t1*epoch)+epoch*cos(4*pi/t1*epoch)+epoch*sin(6*pi/t1*epoch)+epoch*cos(6*pi/t1*epoch)+epoch*sin(8*pi/t1*epoch)+epoch*cos(8*pi/t1*epoch)+epoch*sin(10*pi/t1*epoch)+epoch*cos(10*pi/t1*epoch)+x_sim+y_sim+z_sim+Vx_sim+Vy_sim+Vz_sim, ddi)
lmY <- lm(y ~ epoch+sin(2*pi/t2*epoch)+cos(2*pi/t2*epoch)+sin(4*pi/t2*epoch)+cos(4*pi/t2*epoch)+sin(6*pi/t2*epoch)+cos(6*pi/t2*epoch)+sin(8*pi/t2*epoch)+cos(8*pi/t2*epoch)+sin(10*pi/t2*epoch)+cos(10*pi/t2*epoch)+epoch*sin(2*pi/t2*epoch)+epoch*cos(2*pi/t2*epoch)+epoch*sin(4*pi/t2*epoch)+epoch*cos(4*pi/t2*epoch)+epoch*sin(6*pi/t2*epoch)+epoch*cos(6*pi/t2*epoch)+epoch*sin(8*pi/t2*epoch)+epoch*cos(8*pi/t2*epoch)+epoch*sin(10*pi/t2*epoch)+epoch*cos(10*pi/t2*epoch)+x_sim+y_sim+z_sim+Vx_sim+Vy_sim+Vz_sim, ddi)
lmZ <- lm(z ~ epoch+sin(2*pi/t3*epoch)+cos(2*pi/t3*epoch)+sin(4*pi/t3*epoch)+cos(4*pi/t3*epoch)+sin(6*pi/t3*epoch)+cos(6*pi/t3*epoch)+sin(8*pi/t3*epoch)+cos(8*pi/t3*epoch)+sin(10*pi/t3*epoch)+cos(10*pi/t3*epoch)+epoch*sin(2*pi/t3*epoch)+epoch*cos(2*pi/t3*epoch)+epoch*sin(4*pi/t3*epoch)+epoch*cos(4*pi/t3*epoch)+epoch*sin(6*pi/t3*epoch)+epoch*cos(6*pi/t3*epoch)+epoch*sin(8*pi/t3*epoch)+epoch*cos(8*pi/t3*epoch)+epoch*sin(10*pi/t3*epoch)+epoch*cos(10*pi/t3*epoch)+x_sim+y_sim+z_sim+Vx_sim+Vy_sim+Vz_sim, ddi)
lmVx <- lm(Vx ~ epoch+sin(2*pi/t4*epoch)+cos(2*pi/t4*epoch)+sin(4*pi/t4*epoch)+cos(4*pi/t4*epoch)+sin(6*pi/t4*epoch)+cos(6*pi/t4*epoch)+sin(8*pi/t4*epoch)+cos(8*pi/t4*epoch)+sin(10*pi/t4*epoch)+cos(10*pi/t4*epoch)+epoch*sin(2*pi/t4*epoch)+epoch*cos(2*pi/t4*epoch)+epoch*sin(4*pi/t4*epoch)+epoch*cos(4*pi/t4*epoch)+epoch*sin(6*pi/t4*epoch)+epoch*cos(6*pi/t4*epoch)+epoch*sin(8*pi/t4*epoch)+epoch*cos(8*pi/t4*epoch)+epoch*sin(10*pi/t4*epoch)+epoch*cos(10*pi/t4*epoch)+x_sim+y_sim+z_sim+Vx_sim+Vy_sim+Vz_sim, ddi)
lmVy <- lm(Vy ~ epoch+sin(2*pi/t5*epoch)+cos(2*pi/t5*epoch)+sin(4*pi/t5*epoch)+cos(4*pi/t5*epoch)+sin(6*pi/t5*epoch)+cos(6*pi/t5*epoch)+sin(8*pi/t5*epoch)+cos(8*pi/t5*epoch)+sin(10*pi/t5*epoch)+cos(10*pi/t5*epoch)+epoch*sin(2*pi/t5*epoch)+epoch*cos(2*pi/t5*epoch)+epoch*sin(4*pi/t5*epoch)+epoch*cos(4*pi/t5*epoch)+epoch*sin(6*pi/t5*epoch)+epoch*cos(6*pi/t5*epoch)+epoch*sin(8*pi/t5*epoch)+epoch*cos(8*pi/t5*epoch)+epoch*sin(10*pi/t5*epoch)+epoch*cos(10*pi/t5*epoch)+x_sim+y_sim+z_sim+Vx_sim+Vy_sim+Vz_sim, ddi)
lmVz <- lm(Vz ~ epoch+sin(2*pi/t6*epoch)+cos(2*pi/t6*epoch)+sin(4*pi/t6*epoch)+cos(4*pi/t6*epoch)+sin(6*pi/t6*epoch)+cos(6*pi/t6*epoch)+sin(8*pi/t6*epoch)+cos(8*pi/t6*epoch)+sin(10*pi/t6*epoch)+cos(10*pi/t6*epoch)+epoch*sin(2*pi/t6*epoch)+epoch*cos(2*pi/t6*epoch)+epoch*sin(4*pi/t6*epoch)+epoch*cos(4*pi/t6*epoch)+epoch*sin(6*pi/t6*epoch)+epoch*cos(6*pi/t6*epoch)+epoch*sin(8*pi/t6*epoch)+epoch*cos(8*pi/t6*epoch)+epoch*sin(10*pi/t6*epoch)+epoch*cos(10*pi/t6*epoch)+x_sim+y_sim+z_sim+Vx_sim+Vy_sim+Vz_sim, ddi)
if (i == unique(badsat$sat_id)[1]) {
ans <- data.frame(id = testi$id, sat_id=testi$sat_id, epoch=testi$epoch, x=predict(lmX, testi), y=predict(lmY, testi), z=predict(lmZ, testi), Vx=predict(lmVx, testi), Vy=predict(lmVy, testi), Vz=predict(lmVz, testi))
} else{
ans <- rbind(ans, data.frame(id = testi$id, sat_id=testi$sat_id, epoch=testi$epoch, x=predict(lmX, testi), y=predict(lmY, testi), z=predict(lmZ, testi), Vx=predict(lmVx, testi), Vy=predict(lmVy, testi), Vz=predict(lmVz, testi)))
}
}
[1] 0
[1] 249
[1] 37
[1] 253
[1] 372
[1] 473
[1] 514
[1] 523
[1] 587
for (i in unique(badsat$sat_id)) {
print(i)
sat <- filter(train, sat_id==i)
sat_pred <- filter(ans, sat_id==i)
plot(sat_pred$epoch, sat_pred$x, col="red", type="l")
lines(sat$epoch, sat$x, type = "l", col="blue")
}
[1] 0
[1] 249

[1] 37

[1] 253

[1] 372

[1] 473

[1] 514

[1] 523

[1] 587


Ridge regression
for (i in unique(badsat$sat_id)){
print(i)
ddi <- filter(dd, sat_id==i)
testi <- filter(dd, sat_id==i)
testi <- rbind(select(testi, id, sat_id, epoch, x_sim, y_sim, z_sim, Vx_sim, Vy_sim, Vz_sim), filter(test, sat_id==i))
t1 <- unlist(TT[i+1,1])
t2 <- unlist(TT[i+1,2])
t3 <- unlist(TT[i+1,3])
t4 <- unlist(TT[i+1,4])
t5 <- unlist(TT[i+1,5])
t6 <- unlist(TT[i+1,6])
lmX <- linearRidge(x ~ epoch+sin(2*pi/t1*epoch)+cos(2*pi/t1*epoch)+sin(4*pi/t1*epoch)+cos(4*pi/t1*epoch)+sin(6*pi/t1*epoch)+cos(6*pi/t1*epoch)+sin(8*pi/t1*epoch)+cos(8*pi/t1*epoch)+sin(10*pi/t1*epoch)+cos(10*pi/t1*epoch)+epoch*sin(2*pi/t1*epoch)+epoch*cos(2*pi/t1*epoch)+epoch*sin(4*pi/t1*epoch)+epoch*cos(4*pi/t1*epoch)+epoch*sin(6*pi/t1*epoch)+epoch*cos(6*pi/t1*epoch)+epoch*sin(8*pi/t1*epoch)+epoch*cos(8*pi/t1*epoch)+epoch*sin(10*pi/t1*epoch)+epoch*cos(10*pi/t1*epoch)+x_sim+y_sim+z_sim+Vx_sim+Vy_sim+Vz_sim, ddi, scaling="scale", lambda = 10^seq(-3,2,.1))
lmY <- linearRidge(y ~ epoch+sin(2*pi/t2*epoch)+cos(2*pi/t2*epoch)+sin(4*pi/t2*epoch)+cos(4*pi/t2*epoch)+sin(6*pi/t2*epoch)+cos(6*pi/t2*epoch)+sin(8*pi/t2*epoch)+cos(8*pi/t2*epoch)+sin(10*pi/t2*epoch)+cos(10*pi/t2*epoch)+epoch*sin(2*pi/t2*epoch)+epoch*cos(2*pi/t2*epoch)+epoch*sin(4*pi/t2*epoch)+epoch*cos(4*pi/t2*epoch)+epoch*sin(6*pi/t2*epoch)+epoch*cos(6*pi/t2*epoch)+epoch*sin(8*pi/t2*epoch)+epoch*cos(8*pi/t2*epoch)+epoch*sin(10*pi/t2*epoch)+epoch*cos(10*pi/t2*epoch)+x_sim+y_sim+z_sim+Vx_sim+Vy_sim+Vz_sim, ddi)
lmZ <- linearRidge(z ~ epoch+sin(2*pi/t3*epoch)+cos(2*pi/t3*epoch)+sin(4*pi/t3*epoch)+cos(4*pi/t3*epoch)+sin(6*pi/t3*epoch)+cos(6*pi/t3*epoch)+sin(8*pi/t3*epoch)+cos(8*pi/t3*epoch)+sin(10*pi/t3*epoch)+cos(10*pi/t3*epoch)+epoch*sin(2*pi/t3*epoch)+epoch*cos(2*pi/t3*epoch)+epoch*sin(4*pi/t3*epoch)+epoch*cos(4*pi/t3*epoch)+epoch*sin(6*pi/t3*epoch)+epoch*cos(6*pi/t3*epoch)+epoch*sin(8*pi/t3*epoch)+epoch*cos(8*pi/t3*epoch)+epoch*sin(10*pi/t3*epoch)+epoch*cos(10*pi/t3*epoch)+x_sim+y_sim+z_sim+Vx_sim+Vy_sim+Vz_sim, ddi)
lmVx <- linearRidge(Vx ~ epoch+sin(2*pi/t4*epoch)+cos(2*pi/t4*epoch)+sin(4*pi/t4*epoch)+cos(4*pi/t4*epoch)+sin(6*pi/t4*epoch)+cos(6*pi/t4*epoch)+sin(8*pi/t4*epoch)+cos(8*pi/t4*epoch)+sin(10*pi/t4*epoch)+cos(10*pi/t4*epoch)+epoch*sin(2*pi/t4*epoch)+epoch*cos(2*pi/t4*epoch)+epoch*sin(4*pi/t4*epoch)+epoch*cos(4*pi/t4*epoch)+epoch*sin(6*pi/t4*epoch)+epoch*cos(6*pi/t4*epoch)+epoch*sin(8*pi/t4*epoch)+epoch*cos(8*pi/t4*epoch)+epoch*sin(10*pi/t4*epoch)+epoch*cos(10*pi/t4*epoch)+x_sim+y_sim+z_sim+Vx_sim+Vy_sim+Vz_sim, ddi)
lmVy <- linearRidge(Vy ~ epoch+sin(2*pi/t5*epoch)+cos(2*pi/t5*epoch)+sin(4*pi/t5*epoch)+cos(4*pi/t5*epoch)+sin(6*pi/t5*epoch)+cos(6*pi/t5*epoch)+sin(8*pi/t5*epoch)+cos(8*pi/t5*epoch)+sin(10*pi/t5*epoch)+cos(10*pi/t5*epoch)+epoch*sin(2*pi/t5*epoch)+epoch*cos(2*pi/t5*epoch)+epoch*sin(4*pi/t5*epoch)+epoch*cos(4*pi/t5*epoch)+epoch*sin(6*pi/t5*epoch)+epoch*cos(6*pi/t5*epoch)+epoch*sin(8*pi/t5*epoch)+epoch*cos(8*pi/t5*epoch)+epoch*sin(10*pi/t5*epoch)+epoch*cos(10*pi/t5*epoch)+x_sim+y_sim+z_sim+Vx_sim+Vy_sim+Vz_sim, ddi)
lmVz <- linearRidge(Vz ~ epoch+sin(2*pi/t6*epoch)+cos(2*pi/t6*epoch)+sin(4*pi/t6*epoch)+cos(4*pi/t6*epoch)+sin(6*pi/t6*epoch)+cos(6*pi/t6*epoch)+sin(8*pi/t6*epoch)+cos(8*pi/t6*epoch)+sin(10*pi/t6*epoch)+cos(10*pi/t6*epoch)+epoch*sin(2*pi/t6*epoch)+epoch*cos(2*pi/t6*epoch)+epoch*sin(4*pi/t6*epoch)+epoch*cos(4*pi/t6*epoch)+epoch*sin(6*pi/t6*epoch)+epoch*cos(6*pi/t6*epoch)+epoch*sin(8*pi/t6*epoch)+epoch*cos(8*pi/t6*epoch)+epoch*sin(10*pi/t6*epoch)+epoch*cos(10*pi/t6*epoch)+x_sim+y_sim+z_sim+Vx_sim+Vy_sim+Vz_sim, ddi)
if (i == unique(badsat$sat_id)[1]) {
ans <- data.frame(id = testi$id, sat_id=testi$sat_id, epoch=testi$epoch, x=predict(lmX, testi), y=predict(lmY, testi), z=predict(lmZ, testi), Vx=predict(lmVx, testi), Vy=predict(lmVy, testi), Vz=predict(lmVz, testi))
} else{
ans <- rbind(ans, data.frame(id = testi$id, sat_id=testi$sat_id, epoch=testi$epoch, x=predict(lmX, testi), y=predict(lmY, testi), z=predict(lmZ, testi), Vx=predict(lmVx, testi), Vy=predict(lmVy, testi), Vz=predict(lmVz, testi)))
}
}
[1] 0
Error in as.matrix(mm) %*% beta : argumentos no compatibles
for (i in unique(badsat$sat_id)) {
print(i)
sat <- filter(train, sat_id==i)
sat_pred <- filter(ans, sat_id==i)
plot(sat_pred$epoch, sat_pred$x, col="red", type="l")
lines(sat$epoch, sat$x, type = "l", col="blue")
}
[1] 0
[1] 249

[1] 37

[1] 253

[1] 372

[1] 473

[1] 514

[1] 523

[1] 587


minims <- function(v) {
ans <- c()
for (i in 2:(length(v)-1)) {
if (v[i] < v[i+1] && v[i] < v[i-1]) {
ans <- c(ans, i)
}
}
ans
}
maxims <- function(v) {
ans <- c()
for (i in 2:(length(v)-1)) {
if (v[i] > v[i+1] && v[i] > v[i-1]) {
ans <- c(ans, i)
}
}
ans
}
ddi <- filter(train, sat_id==badsat$sat_id[3])
tti <- data.frame(id=ddi$id, sat_id=ddi$sat_id, epoch=ddi$epoch, x=predict(lmX, ddi), y=predict(lmY, ddi), z=predict(lmZ, ddi), Vx=predict(lmVX, ddi), Vy=predict(lmVY, ddi), VZ=predict(lmVZ, ddi))
tti <- filter(ans, sat_id==badsat$sat_id[3])
minddiX <- ddi[minims(ddi$x),]
rectaXdown <- lm(x ~ epoch, data = minddiX)
maxddiX <- ddi[maxims(ddi$x),]
rectaXup <- lm(x ~ epoch, data = maxddiX)
minttiX <- tti[minims(tti$x),]
rectaXdownt <- lm(x ~ epoch, data = minttiX)
maxttiX <- tti[maxims(tti$x),]
rectaXupt <- lm(x ~ epoch, data = maxttiX)
plot(minttiX$epoch, minttiX$x)
points(maxttiX$epoch, maxttiX$x)

c <- predict(rectaXdown, tti)
d <- predict(rectaXup, tti)
tti$x <- (tti$x - predict(rectaXdownt, tti)) * (d-c) / (predict(rectaXupt,tti) - predict(rectaXdownt, tti)) + c
plot(tti$epoch, tti$x, col="red", type="p", ylim=c(min(sat$x),max(sat$x)))
lines(sat$epoch, sat$x, type = "p", col="blue")

Exportar
sat <- filter(train, sat_id==badsat$sat_id[3])
sat_pred <- filter(ans, sat_id==badsat$sat_id[3])
write_csv(ddi, "train.csv", quote=F)
write_csv(tti, "submission.csv", quote=F)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKTGlicmVpYXMKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5IChjYXIpCmxpYnJhcnkgKHJpZGdlKQpgYGAKCkRhdGEKYGBge3J9CnRyYWluIDwtIHJlYWRfY3N2KCIuLi8uLi9kYXRhL3RyYWluLmNzdiIpCnRlc3QgPC0gcmVhZF9jc3YoIi4uLy4uL2RhdGEvdGVzdC5jc3YiKQoKdGVzdCRlcG9jaCA8LSBhcy5udW1lcmljKGFzLlBPU0lYY3QodGVzdCRlcG9jaCkpCnRyYWluJGVwb2NoIDwtIGFzLm51bWVyaWMoYXMuUE9TSVhjdCh0cmFpbiRlcG9jaCkpCnRlc3QkZXBvY2ggPC0gdGVzdCRlcG9jaCAtIG1pbih0cmFpbiRlcG9jaCkKdHJhaW4kZXBvY2ggPC0gdHJhaW4kZXBvY2ggLSBtaW4odHJhaW4kZXBvY2gpCgp0cmFpbiR4IDwtIGFzLm51bWVyaWModHJhaW4keCkKdHJhaW4keSA8LSBhcy5udW1lcmljKHRyYWluJHkpCnRyYWluJHogPC0gYXMubnVtZXJpYyh0cmFpbiR6KQp0cmFpbiRWeCA8LSBhcy5udW1lcmljKHRyYWluJFZ4KQp0cmFpbiRWeSA8LSBhcy5udW1lcmljKHRyYWluJFZ5KQp0cmFpbiRWeiA8LSBhcy5udW1lcmljKHRyYWluJFZ6KQoKVFQgPC0gcmVhZF9jc3YoIi4uLy4uL2RhdGEvcGVyaW9kcy5jc3YiKQpgYGAKClNhdGVsaXRlcyBtYWxvCmBgYHtyfQpiYWRzYXQgPC0gcmVhZF9jc3YoIkJBRFNBVC50eHQiKQpiYWRzYXQKYGBgCgpOb3JtYWwgcmVncmVzc2lvbgpgYGB7cn0KZm9yIChpIGluIHVuaXF1ZShiYWRzYXQkc2F0X2lkKSl7CiAgcHJpbnQoaSkKIGRkaSA8LSBmaWx0ZXIoZGQsIHNhdF9pZD09aSkKIHRlc3RpIDwtIGZpbHRlcihkZCwgc2F0X2lkPT1pKQogdGVzdGkgPC0gcmJpbmQoc2VsZWN0KHRlc3RpLCBpZCwgc2F0X2lkLCBlcG9jaCwgeF9zaW0sIHlfc2ltLCB6X3NpbSwgVnhfc2ltLCBWeV9zaW0sIFZ6X3NpbSksIGZpbHRlcih0ZXN0LCBzYXRfaWQ9PWkpKQogCiAgdDEgPC0gdW5saXN0KFRUW2krMSwxXSkKICB0MiA8LSB1bmxpc3QoVFRbaSsxLDJdKQogIHQzIDwtIHVubGlzdChUVFtpKzEsM10pCiAgdDQgPC0gdW5saXN0KFRUW2krMSw0XSkKICB0NSA8LSB1bmxpc3QoVFRbaSsxLDVdKQogIHQ2IDwtIHVubGlzdChUVFtpKzEsNl0pCiAgCiAgCiBsbVggPC0gbG0oeCB+IGVwb2NoK3NpbigyKnBpL3QxKmVwb2NoKStjb3MoMipwaS90MSplcG9jaCkrc2luKDQqcGkvdDEqZXBvY2gpK2Nvcyg0KnBpL3QxKmVwb2NoKStzaW4oNipwaS90MSplcG9jaCkrY29zKDYqcGkvdDEqZXBvY2gpK3Npbig4KnBpL3QxKmVwb2NoKStjb3MoOCpwaS90MSplcG9jaCkrc2luKDEwKnBpL3QxKmVwb2NoKStjb3MoMTAqcGkvdDEqZXBvY2gpK2Vwb2NoKnNpbigyKnBpL3QxKmVwb2NoKStlcG9jaCpjb3MoMipwaS90MSplcG9jaCkrZXBvY2gqc2luKDQqcGkvdDEqZXBvY2gpK2Vwb2NoKmNvcyg0KnBpL3QxKmVwb2NoKStlcG9jaCpzaW4oNipwaS90MSplcG9jaCkrZXBvY2gqY29zKDYqcGkvdDEqZXBvY2gpK2Vwb2NoKnNpbig4KnBpL3QxKmVwb2NoKStlcG9jaCpjb3MoOCpwaS90MSplcG9jaCkrZXBvY2gqc2luKDEwKnBpL3QxKmVwb2NoKStlcG9jaCpjb3MoMTAqcGkvdDEqZXBvY2gpK3hfc2ltK3lfc2ltK3pfc2ltK1Z4X3NpbStWeV9zaW0rVnpfc2ltLCBkZGkpCiAKIGxtWSA8LSBsbSh5IH4gZXBvY2grc2luKDIqcGkvdDIqZXBvY2gpK2NvcygyKnBpL3QyKmVwb2NoKStzaW4oNCpwaS90MiplcG9jaCkrY29zKDQqcGkvdDIqZXBvY2gpK3Npbig2KnBpL3QyKmVwb2NoKStjb3MoNipwaS90MiplcG9jaCkrc2luKDgqcGkvdDIqZXBvY2gpK2Nvcyg4KnBpL3QyKmVwb2NoKStzaW4oMTAqcGkvdDIqZXBvY2gpK2NvcygxMCpwaS90MiplcG9jaCkrZXBvY2gqc2luKDIqcGkvdDIqZXBvY2gpK2Vwb2NoKmNvcygyKnBpL3QyKmVwb2NoKStlcG9jaCpzaW4oNCpwaS90MiplcG9jaCkrZXBvY2gqY29zKDQqcGkvdDIqZXBvY2gpK2Vwb2NoKnNpbig2KnBpL3QyKmVwb2NoKStlcG9jaCpjb3MoNipwaS90MiplcG9jaCkrZXBvY2gqc2luKDgqcGkvdDIqZXBvY2gpK2Vwb2NoKmNvcyg4KnBpL3QyKmVwb2NoKStlcG9jaCpzaW4oMTAqcGkvdDIqZXBvY2gpK2Vwb2NoKmNvcygxMCpwaS90MiplcG9jaCkreF9zaW0reV9zaW0rel9zaW0rVnhfc2ltK1Z5X3NpbStWel9zaW0sIGRkaSkKIAogbG1aIDwtIGxtKHogfiBlcG9jaCtzaW4oMipwaS90MyplcG9jaCkrY29zKDIqcGkvdDMqZXBvY2gpK3Npbig0KnBpL3QzKmVwb2NoKStjb3MoNCpwaS90MyplcG9jaCkrc2luKDYqcGkvdDMqZXBvY2gpK2Nvcyg2KnBpL3QzKmVwb2NoKStzaW4oOCpwaS90MyplcG9jaCkrY29zKDgqcGkvdDMqZXBvY2gpK3NpbigxMCpwaS90MyplcG9jaCkrY29zKDEwKnBpL3QzKmVwb2NoKStlcG9jaCpzaW4oMipwaS90MyplcG9jaCkrZXBvY2gqY29zKDIqcGkvdDMqZXBvY2gpK2Vwb2NoKnNpbig0KnBpL3QzKmVwb2NoKStlcG9jaCpjb3MoNCpwaS90MyplcG9jaCkrZXBvY2gqc2luKDYqcGkvdDMqZXBvY2gpK2Vwb2NoKmNvcyg2KnBpL3QzKmVwb2NoKStlcG9jaCpzaW4oOCpwaS90MyplcG9jaCkrZXBvY2gqY29zKDgqcGkvdDMqZXBvY2gpK2Vwb2NoKnNpbigxMCpwaS90MyplcG9jaCkrZXBvY2gqY29zKDEwKnBpL3QzKmVwb2NoKSt4X3NpbSt5X3NpbSt6X3NpbStWeF9zaW0rVnlfc2ltK1Z6X3NpbSwgZGRpKQoKIGxtVnggPC0gbG0oVnggfiBlcG9jaCtzaW4oMipwaS90NCplcG9jaCkrY29zKDIqcGkvdDQqZXBvY2gpK3Npbig0KnBpL3Q0KmVwb2NoKStjb3MoNCpwaS90NCplcG9jaCkrc2luKDYqcGkvdDQqZXBvY2gpK2Nvcyg2KnBpL3Q0KmVwb2NoKStzaW4oOCpwaS90NCplcG9jaCkrY29zKDgqcGkvdDQqZXBvY2gpK3NpbigxMCpwaS90NCplcG9jaCkrY29zKDEwKnBpL3Q0KmVwb2NoKStlcG9jaCpzaW4oMipwaS90NCplcG9jaCkrZXBvY2gqY29zKDIqcGkvdDQqZXBvY2gpK2Vwb2NoKnNpbig0KnBpL3Q0KmVwb2NoKStlcG9jaCpjb3MoNCpwaS90NCplcG9jaCkrZXBvY2gqc2luKDYqcGkvdDQqZXBvY2gpK2Vwb2NoKmNvcyg2KnBpL3Q0KmVwb2NoKStlcG9jaCpzaW4oOCpwaS90NCplcG9jaCkrZXBvY2gqY29zKDgqcGkvdDQqZXBvY2gpK2Vwb2NoKnNpbigxMCpwaS90NCplcG9jaCkrZXBvY2gqY29zKDEwKnBpL3Q0KmVwb2NoKSt4X3NpbSt5X3NpbSt6X3NpbStWeF9zaW0rVnlfc2ltK1Z6X3NpbSwgZGRpKQogCiBsbVZ5IDwtIGxtKFZ5IH4gZXBvY2grc2luKDIqcGkvdDUqZXBvY2gpK2NvcygyKnBpL3Q1KmVwb2NoKStzaW4oNCpwaS90NSplcG9jaCkrY29zKDQqcGkvdDUqZXBvY2gpK3Npbig2KnBpL3Q1KmVwb2NoKStjb3MoNipwaS90NSplcG9jaCkrc2luKDgqcGkvdDUqZXBvY2gpK2Nvcyg4KnBpL3Q1KmVwb2NoKStzaW4oMTAqcGkvdDUqZXBvY2gpK2NvcygxMCpwaS90NSplcG9jaCkrZXBvY2gqc2luKDIqcGkvdDUqZXBvY2gpK2Vwb2NoKmNvcygyKnBpL3Q1KmVwb2NoKStlcG9jaCpzaW4oNCpwaS90NSplcG9jaCkrZXBvY2gqY29zKDQqcGkvdDUqZXBvY2gpK2Vwb2NoKnNpbig2KnBpL3Q1KmVwb2NoKStlcG9jaCpjb3MoNipwaS90NSplcG9jaCkrZXBvY2gqc2luKDgqcGkvdDUqZXBvY2gpK2Vwb2NoKmNvcyg4KnBpL3Q1KmVwb2NoKStlcG9jaCpzaW4oMTAqcGkvdDUqZXBvY2gpK2Vwb2NoKmNvcygxMCpwaS90NSplcG9jaCkreF9zaW0reV9zaW0rel9zaW0rVnhfc2ltK1Z5X3NpbStWel9zaW0sIGRkaSkKIAogbG1WeiA8LSBsbShWeiB+IGVwb2NoK3NpbigyKnBpL3Q2KmVwb2NoKStjb3MoMipwaS90NiplcG9jaCkrc2luKDQqcGkvdDYqZXBvY2gpK2Nvcyg0KnBpL3Q2KmVwb2NoKStzaW4oNipwaS90NiplcG9jaCkrY29zKDYqcGkvdDYqZXBvY2gpK3Npbig4KnBpL3Q2KmVwb2NoKStjb3MoOCpwaS90NiplcG9jaCkrc2luKDEwKnBpL3Q2KmVwb2NoKStjb3MoMTAqcGkvdDYqZXBvY2gpK2Vwb2NoKnNpbigyKnBpL3Q2KmVwb2NoKStlcG9jaCpjb3MoMipwaS90NiplcG9jaCkrZXBvY2gqc2luKDQqcGkvdDYqZXBvY2gpK2Vwb2NoKmNvcyg0KnBpL3Q2KmVwb2NoKStlcG9jaCpzaW4oNipwaS90NiplcG9jaCkrZXBvY2gqY29zKDYqcGkvdDYqZXBvY2gpK2Vwb2NoKnNpbig4KnBpL3Q2KmVwb2NoKStlcG9jaCpjb3MoOCpwaS90NiplcG9jaCkrZXBvY2gqc2luKDEwKnBpL3Q2KmVwb2NoKStlcG9jaCpjb3MoMTAqcGkvdDYqZXBvY2gpK3hfc2ltK3lfc2ltK3pfc2ltK1Z4X3NpbStWeV9zaW0rVnpfc2ltLCBkZGkpCiAKICAKIGlmIChpID09IHVuaXF1ZShiYWRzYXQkc2F0X2lkKVsxXSkgewogIGFucyA8LSBkYXRhLmZyYW1lKGlkID0gdGVzdGkkaWQsIHNhdF9pZD10ZXN0aSRzYXRfaWQsIGVwb2NoPXRlc3RpJGVwb2NoLCB4PXByZWRpY3QobG1YLCB0ZXN0aSksIHk9cHJlZGljdChsbVksIHRlc3RpKSwgej1wcmVkaWN0KGxtWiwgdGVzdGkpLCBWeD1wcmVkaWN0KGxtVngsIHRlc3RpKSwgVnk9cHJlZGljdChsbVZ5LCB0ZXN0aSksIFZ6PXByZWRpY3QobG1WeiwgdGVzdGkpKQogfSBlbHNlewogIGFucyA8LSByYmluZChhbnMsIGRhdGEuZnJhbWUoaWQgPSB0ZXN0aSRpZCwgc2F0X2lkPXRlc3RpJHNhdF9pZCwgZXBvY2g9dGVzdGkkZXBvY2gsIHg9cHJlZGljdChsbVgsIHRlc3RpKSwgeT1wcmVkaWN0KGxtWSwgdGVzdGkpLCB6PXByZWRpY3QobG1aLCB0ZXN0aSksIFZ4PXByZWRpY3QobG1WeCwgdGVzdGkpLCBWeT1wcmVkaWN0KGxtVnksIHRlc3RpKSwgVno9cHJlZGljdChsbVZ6LCB0ZXN0aSkpKQogfQp9CmBgYAoKYGBge3J9CmZvciAoaSBpbiB1bmlxdWUoYmFkc2F0JHNhdF9pZCkpIHsKICBwcmludChpKQogIHNhdCA8LSBmaWx0ZXIodHJhaW4sIHNhdF9pZD09aSkKICBzYXRfcHJlZCA8LSBmaWx0ZXIoYW5zLCBzYXRfaWQ9PWkpCiAgCiAgcGxvdChzYXRfcHJlZCRlcG9jaCwgc2F0X3ByZWQkeCwgY29sPSJyZWQiLCB0eXBlPSJsIikKICBsaW5lcyhzYXQkZXBvY2gsIHNhdCR4LCB0eXBlID0gImwiLCBjb2w9ImJsdWUiKQp9CmBgYAoKUmlkZ2UgcmVncmVzc2lvbgpgYGB7cn0KZm9yIChpIGluIHVuaXF1ZShiYWRzYXQkc2F0X2lkKSl7CiAgcHJpbnQoaSkKIGRkaSA8LSBmaWx0ZXIoZGQsIHNhdF9pZD09aSkKIHRlc3RpIDwtIGZpbHRlcihkZCwgc2F0X2lkPT1pKQogdGVzdGkgPC0gcmJpbmQoc2VsZWN0KHRlc3RpLCBpZCwgc2F0X2lkLCBlcG9jaCwgeF9zaW0sIHlfc2ltLCB6X3NpbSwgVnhfc2ltLCBWeV9zaW0sIFZ6X3NpbSksIGZpbHRlcih0ZXN0LCBzYXRfaWQ9PWkpKQogCiAgdDEgPC0gdW5saXN0KFRUW2krMSwxXSkKICB0MiA8LSB1bmxpc3QoVFRbaSsxLDJdKQogIHQzIDwtIHVubGlzdChUVFtpKzEsM10pCiAgdDQgPC0gdW5saXN0KFRUW2krMSw0XSkKICB0NSA8LSB1bmxpc3QoVFRbaSsxLDVdKQogIHQ2IDwtIHVubGlzdChUVFtpKzEsNl0pCiAgCiAgCiBsbVggPC0gbGluZWFyUmlkZ2UoeCB+IGVwb2NoK3NpbigyKnBpL3QxKmVwb2NoKStjb3MoMipwaS90MSplcG9jaCkrc2luKDQqcGkvdDEqZXBvY2gpK2Nvcyg0KnBpL3QxKmVwb2NoKStzaW4oNipwaS90MSplcG9jaCkrY29zKDYqcGkvdDEqZXBvY2gpK3Npbig4KnBpL3QxKmVwb2NoKStjb3MoOCpwaS90MSplcG9jaCkrc2luKDEwKnBpL3QxKmVwb2NoKStjb3MoMTAqcGkvdDEqZXBvY2gpK2Vwb2NoKnNpbigyKnBpL3QxKmVwb2NoKStlcG9jaCpjb3MoMipwaS90MSplcG9jaCkrZXBvY2gqc2luKDQqcGkvdDEqZXBvY2gpK2Vwb2NoKmNvcyg0KnBpL3QxKmVwb2NoKStlcG9jaCpzaW4oNipwaS90MSplcG9jaCkrZXBvY2gqY29zKDYqcGkvdDEqZXBvY2gpK2Vwb2NoKnNpbig4KnBpL3QxKmVwb2NoKStlcG9jaCpjb3MoOCpwaS90MSplcG9jaCkrZXBvY2gqc2luKDEwKnBpL3QxKmVwb2NoKStlcG9jaCpjb3MoMTAqcGkvdDEqZXBvY2gpK3hfc2ltK3lfc2ltK3pfc2ltK1Z4X3NpbStWeV9zaW0rVnpfc2ltLCBkZGksIHNjYWxpbmc9InNjYWxlIiwgbGFtYmRhID0gMTBec2VxKC0zLDIsLjEpKQogCiBsbVkgPC0gbGluZWFyUmlkZ2UoeSB+IGVwb2NoK3NpbigyKnBpL3QyKmVwb2NoKStjb3MoMipwaS90MiplcG9jaCkrc2luKDQqcGkvdDIqZXBvY2gpK2Nvcyg0KnBpL3QyKmVwb2NoKStzaW4oNipwaS90MiplcG9jaCkrY29zKDYqcGkvdDIqZXBvY2gpK3Npbig4KnBpL3QyKmVwb2NoKStjb3MoOCpwaS90MiplcG9jaCkrc2luKDEwKnBpL3QyKmVwb2NoKStjb3MoMTAqcGkvdDIqZXBvY2gpK2Vwb2NoKnNpbigyKnBpL3QyKmVwb2NoKStlcG9jaCpjb3MoMipwaS90MiplcG9jaCkrZXBvY2gqc2luKDQqcGkvdDIqZXBvY2gpK2Vwb2NoKmNvcyg0KnBpL3QyKmVwb2NoKStlcG9jaCpzaW4oNipwaS90MiplcG9jaCkrZXBvY2gqY29zKDYqcGkvdDIqZXBvY2gpK2Vwb2NoKnNpbig4KnBpL3QyKmVwb2NoKStlcG9jaCpjb3MoOCpwaS90MiplcG9jaCkrZXBvY2gqc2luKDEwKnBpL3QyKmVwb2NoKStlcG9jaCpjb3MoMTAqcGkvdDIqZXBvY2gpK3hfc2ltK3lfc2ltK3pfc2ltK1Z4X3NpbStWeV9zaW0rVnpfc2ltLCBkZGkpCiAKIGxtWiA8LSBsaW5lYXJSaWRnZSh6IH4gZXBvY2grc2luKDIqcGkvdDMqZXBvY2gpK2NvcygyKnBpL3QzKmVwb2NoKStzaW4oNCpwaS90MyplcG9jaCkrY29zKDQqcGkvdDMqZXBvY2gpK3Npbig2KnBpL3QzKmVwb2NoKStjb3MoNipwaS90MyplcG9jaCkrc2luKDgqcGkvdDMqZXBvY2gpK2Nvcyg4KnBpL3QzKmVwb2NoKStzaW4oMTAqcGkvdDMqZXBvY2gpK2NvcygxMCpwaS90MyplcG9jaCkrZXBvY2gqc2luKDIqcGkvdDMqZXBvY2gpK2Vwb2NoKmNvcygyKnBpL3QzKmVwb2NoKStlcG9jaCpzaW4oNCpwaS90MyplcG9jaCkrZXBvY2gqY29zKDQqcGkvdDMqZXBvY2gpK2Vwb2NoKnNpbig2KnBpL3QzKmVwb2NoKStlcG9jaCpjb3MoNipwaS90MyplcG9jaCkrZXBvY2gqc2luKDgqcGkvdDMqZXBvY2gpK2Vwb2NoKmNvcyg4KnBpL3QzKmVwb2NoKStlcG9jaCpzaW4oMTAqcGkvdDMqZXBvY2gpK2Vwb2NoKmNvcygxMCpwaS90MyplcG9jaCkreF9zaW0reV9zaW0rel9zaW0rVnhfc2ltK1Z5X3NpbStWel9zaW0sIGRkaSkKCiBsbVZ4IDwtIGxpbmVhclJpZGdlKFZ4IH4gZXBvY2grc2luKDIqcGkvdDQqZXBvY2gpK2NvcygyKnBpL3Q0KmVwb2NoKStzaW4oNCpwaS90NCplcG9jaCkrY29zKDQqcGkvdDQqZXBvY2gpK3Npbig2KnBpL3Q0KmVwb2NoKStjb3MoNipwaS90NCplcG9jaCkrc2luKDgqcGkvdDQqZXBvY2gpK2Nvcyg4KnBpL3Q0KmVwb2NoKStzaW4oMTAqcGkvdDQqZXBvY2gpK2NvcygxMCpwaS90NCplcG9jaCkrZXBvY2gqc2luKDIqcGkvdDQqZXBvY2gpK2Vwb2NoKmNvcygyKnBpL3Q0KmVwb2NoKStlcG9jaCpzaW4oNCpwaS90NCplcG9jaCkrZXBvY2gqY29zKDQqcGkvdDQqZXBvY2gpK2Vwb2NoKnNpbig2KnBpL3Q0KmVwb2NoKStlcG9jaCpjb3MoNipwaS90NCplcG9jaCkrZXBvY2gqc2luKDgqcGkvdDQqZXBvY2gpK2Vwb2NoKmNvcyg4KnBpL3Q0KmVwb2NoKStlcG9jaCpzaW4oMTAqcGkvdDQqZXBvY2gpK2Vwb2NoKmNvcygxMCpwaS90NCplcG9jaCkreF9zaW0reV9zaW0rel9zaW0rVnhfc2ltK1Z5X3NpbStWel9zaW0sIGRkaSkKIAogbG1WeSA8LSBsaW5lYXJSaWRnZShWeSB+IGVwb2NoK3NpbigyKnBpL3Q1KmVwb2NoKStjb3MoMipwaS90NSplcG9jaCkrc2luKDQqcGkvdDUqZXBvY2gpK2Nvcyg0KnBpL3Q1KmVwb2NoKStzaW4oNipwaS90NSplcG9jaCkrY29zKDYqcGkvdDUqZXBvY2gpK3Npbig4KnBpL3Q1KmVwb2NoKStjb3MoOCpwaS90NSplcG9jaCkrc2luKDEwKnBpL3Q1KmVwb2NoKStjb3MoMTAqcGkvdDUqZXBvY2gpK2Vwb2NoKnNpbigyKnBpL3Q1KmVwb2NoKStlcG9jaCpjb3MoMipwaS90NSplcG9jaCkrZXBvY2gqc2luKDQqcGkvdDUqZXBvY2gpK2Vwb2NoKmNvcyg0KnBpL3Q1KmVwb2NoKStlcG9jaCpzaW4oNipwaS90NSplcG9jaCkrZXBvY2gqY29zKDYqcGkvdDUqZXBvY2gpK2Vwb2NoKnNpbig4KnBpL3Q1KmVwb2NoKStlcG9jaCpjb3MoOCpwaS90NSplcG9jaCkrZXBvY2gqc2luKDEwKnBpL3Q1KmVwb2NoKStlcG9jaCpjb3MoMTAqcGkvdDUqZXBvY2gpK3hfc2ltK3lfc2ltK3pfc2ltK1Z4X3NpbStWeV9zaW0rVnpfc2ltLCBkZGkpCiAKIGxtVnogPC0gbGluZWFyUmlkZ2UoVnogfiBlcG9jaCtzaW4oMipwaS90NiplcG9jaCkrY29zKDIqcGkvdDYqZXBvY2gpK3Npbig0KnBpL3Q2KmVwb2NoKStjb3MoNCpwaS90NiplcG9jaCkrc2luKDYqcGkvdDYqZXBvY2gpK2Nvcyg2KnBpL3Q2KmVwb2NoKStzaW4oOCpwaS90NiplcG9jaCkrY29zKDgqcGkvdDYqZXBvY2gpK3NpbigxMCpwaS90NiplcG9jaCkrY29zKDEwKnBpL3Q2KmVwb2NoKStlcG9jaCpzaW4oMipwaS90NiplcG9jaCkrZXBvY2gqY29zKDIqcGkvdDYqZXBvY2gpK2Vwb2NoKnNpbig0KnBpL3Q2KmVwb2NoKStlcG9jaCpjb3MoNCpwaS90NiplcG9jaCkrZXBvY2gqc2luKDYqcGkvdDYqZXBvY2gpK2Vwb2NoKmNvcyg2KnBpL3Q2KmVwb2NoKStlcG9jaCpzaW4oOCpwaS90NiplcG9jaCkrZXBvY2gqY29zKDgqcGkvdDYqZXBvY2gpK2Vwb2NoKnNpbigxMCpwaS90NiplcG9jaCkrZXBvY2gqY29zKDEwKnBpL3Q2KmVwb2NoKSt4X3NpbSt5X3NpbSt6X3NpbStWeF9zaW0rVnlfc2ltK1Z6X3NpbSwgZGRpKQogCiAgCiBpZiAoaSA9PSB1bmlxdWUoYmFkc2F0JHNhdF9pZClbMV0pIHsKICBhbnMgPC0gZGF0YS5mcmFtZShpZCA9IHRlc3RpJGlkLCBzYXRfaWQ9dGVzdGkkc2F0X2lkLCBlcG9jaD10ZXN0aSRlcG9jaCwgeD1wcmVkaWN0KGxtWCwgdGVzdGkpLCB5PXByZWRpY3QobG1ZLCB0ZXN0aSksIHo9cHJlZGljdChsbVosIHRlc3RpKSwgVng9cHJlZGljdChsbVZ4LCB0ZXN0aSksIFZ5PXByZWRpY3QobG1WeSwgdGVzdGkpLCBWej1wcmVkaWN0KGxtVnosIHRlc3RpKSkKIH0gZWxzZXsKICBhbnMgPC0gcmJpbmQoYW5zLCBkYXRhLmZyYW1lKGlkID0gdGVzdGkkaWQsIHNhdF9pZD10ZXN0aSRzYXRfaWQsIGVwb2NoPXRlc3RpJGVwb2NoLCB4PXByZWRpY3QobG1YLCB0ZXN0aSksIHk9cHJlZGljdChsbVksIHRlc3RpKSwgej1wcmVkaWN0KGxtWiwgdGVzdGkpLCBWeD1wcmVkaWN0KGxtVngsIHRlc3RpKSwgVnk9cHJlZGljdChsbVZ5LCB0ZXN0aSksIFZ6PXByZWRpY3QobG1WeiwgdGVzdGkpKSkKIH0KfQpgYGAKCmBgYHtyfQpmb3IgKGkgaW4gdW5pcXVlKGJhZHNhdCRzYXRfaWQpKSB7CiAgcHJpbnQoaSkKICBzYXQgPC0gZmlsdGVyKHRyYWluLCBzYXRfaWQ9PWkpCiAgc2F0X3ByZWQgPC0gZmlsdGVyKGFucywgc2F0X2lkPT1pKQogIAogIHBsb3Qoc2F0X3ByZWQkZXBvY2gsIHNhdF9wcmVkJHgsIGNvbD0icmVkIiwgdHlwZT0ibCIpCiAgbGluZXMoc2F0JGVwb2NoLCBzYXQkeCwgdHlwZSA9ICJsIiwgY29sPSJibHVlIikKfQpgYGAKCgpgYGB7cn0KbWluaW1zIDwtIGZ1bmN0aW9uKHYpIHsKICBhbnMgPC0gYygpCiAgZm9yIChpIGluIDI6KGxlbmd0aCh2KS0xKSkgewogICAgaWYgKHZbaV0gPCB2W2krMV0gJiYgdltpXSA8IHZbaS0xXSkgewogICAgICBhbnMgPC0gYyhhbnMsIGkpCiAgICB9CiAgfQogIGFucwp9CgptYXhpbXMgPC0gZnVuY3Rpb24odikgewogIGFucyA8LSBjKCkKICBmb3IgKGkgaW4gMjoobGVuZ3RoKHYpLTEpKSB7CiAgICBpZiAodltpXSA+IHZbaSsxXSAmJiB2W2ldID4gdltpLTFdKSB7CiAgICAgIGFucyA8LSBjKGFucywgaSkKICAgIH0KICB9CiAgYW5zCn0KYGBgCgpgYGB7cn0KZGRpIDwtIGZpbHRlcih0cmFpbiwgc2F0X2lkPT1iYWRzYXQkc2F0X2lkWzNdKQp0dGkgPC0gZGF0YS5mcmFtZShpZD1kZGkkaWQsIHNhdF9pZD1kZGkkc2F0X2lkLCBlcG9jaD1kZGkkZXBvY2gsIHg9cHJlZGljdChsbVgsIGRkaSksIHk9cHJlZGljdChsbVksIGRkaSksIHo9cHJlZGljdChsbVosIGRkaSksIFZ4PXByZWRpY3QobG1WWCwgZGRpKSwgVnk9cHJlZGljdChsbVZZLCBkZGkpLCBWWj1wcmVkaWN0KGxtVlosIGRkaSkpCnR0aSA8LSBmaWx0ZXIoYW5zLCBzYXRfaWQ9PWJhZHNhdCRzYXRfaWRbM10pCgptaW5kZGlYIDwtIGRkaVttaW5pbXMoZGRpJHgpLF0KcmVjdGFYZG93biA8LSBsbSh4IH4gZXBvY2gsIGRhdGEgPSBtaW5kZGlYKQptYXhkZGlYIDwtIGRkaVttYXhpbXMoZGRpJHgpLF0KcmVjdGFYdXAgPC0gbG0oeCB+IGVwb2NoLCBkYXRhID0gbWF4ZGRpWCkKCm1pbnR0aVggPC0gdHRpW21pbmltcyh0dGkkeCksXQpyZWN0YVhkb3dudCA8LSBsbSh4IH4gZXBvY2gsIGRhdGEgPSBtaW50dGlYKQptYXh0dGlYIDwtIHR0aVttYXhpbXModHRpJHgpLF0KcmVjdGFYdXB0IDwtIGxtKHggfiBlcG9jaCwgZGF0YSA9IG1heHR0aVgpCnBsb3QobWludHRpWCRlcG9jaCwgbWludHRpWCR4KQpwb2ludHMobWF4dHRpWCRlcG9jaCwgbWF4dHRpWCR4KQoKYyA8LSBwcmVkaWN0KHJlY3RhWGRvd24sIHR0aSkKZCA8LSBwcmVkaWN0KHJlY3RhWHVwLCB0dGkpCgp0dGkkeCA8LSAodHRpJHggLSBwcmVkaWN0KHJlY3RhWGRvd250LCB0dGkpKSAqIChkLWMpIC8gKHByZWRpY3QocmVjdGFYdXB0LHR0aSkgLSBwcmVkaWN0KHJlY3RhWGRvd250LCB0dGkpKSArIGMKCnBsb3QodHRpJGVwb2NoLCB0dGkkeCwgY29sPSJyZWQiLCB0eXBlPSJwIiwgeWxpbT1jKG1pbihzYXQkeCksbWF4KHNhdCR4KSkpCmxpbmVzKHNhdCRlcG9jaCwgc2F0JHgsIHR5cGUgPSAicCIsIGNvbD0iYmx1ZSIpCmBgYApFeHBvcnRhcgpgYGB7cn0Kc2F0IDwtIGZpbHRlcih0cmFpbiwgc2F0X2lkPT1iYWRzYXQkc2F0X2lkWzNdKQpzYXRfcHJlZCA8LSBmaWx0ZXIoYW5zLCBzYXRfaWQ9PWJhZHNhdCRzYXRfaWRbM10pCgp3cml0ZV9jc3YoZGRpLCAidHJhaW4uY3N2IiwgcXVvdGU9RikKd3JpdGVfY3N2KHR0aSwgInN1Ym1pc3Npb24uY3N2IiwgcXVvdGU9RikKYGBgCgoKCgoK